home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
amber
/
amber.lha
/
Callstate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-25
|
3KB
|
126 lines
/*
* Callstate.c
*
* Machine dependent code to remember and restore the callstate
* so that we can "squirrel" away a user's function call and make it
* later.
*
*/
#include <stream.h>
#include "Defs.h"
#include "Object.h"
#include "Callstate.h"
static char rcsid[] = "$Header: /var/a/oriole/u1/thekkath/amber/RCS/Callstate.c,v 1.1 90/08/22 16:54:31 thekkath Exp Locker: thekkath $";
void Callstate::Init()
{
cs_len = CS_MAXARGS;
cs_argvd = 0;
}
extern void bcopy(char*, char*, int);
Callstate::~Callstate()
{
if (cs_argvd)
delete cs_argvd;
}
//
// Callstate set called with:
// pointer to function to be called later on
// number of args (longwords) it should get called with
// a pointer to the base of those args
//
// We store this information away and later shove it on to the call
// stack of the function we want to call.
//
//
// Copy the arglist into the callstate.
// If there are args,
// and the # args > size of cs space, then
// delete the existing dynamic cs space
// make some new ones
// record size of new cs space
// copy args into new dynamic space
// else, have enough room somewhere. Copy args
// into dynamic space (if we have it), else into
// static area.
//
// comments in Callstate::Call below.
//
void
Callstate::Set(Objany boundObj, PFany f, int argc, int *argv)
{
register int *ap;
cs_bound = boundObj;
cs_func = (PFIany)f;
cs_argc = argc;
if (argc) {
if (argc > cs_len) {
delete cs_argvd;
ap = cs_argvd = new int [argc];
cs_len = cs_argc;
} else {
ap = (cs_argvd) ? cs_argvd : cs_argvs;
}
bcopy((char*)argv, (char*)ap, argc * sizeof(int));
}
}
//
// Perform the actual call.
// XXX MACHDEP
//
Objany
Callstate::Call()
{
int func = (int)cs_func;
int stackbytes = cs_argc * sizeof(long);
int *ap;
int mipscall(Objany,PFIany,int,int *);
// On the mips the first 4 args go in registers the next on
// the stack. The situ is more complicated if one of the args
// is a float.
//
if (cs_argvd) {
ap = cs_argvd;
} else {
ap = cs_argvs;
}
switch(cs_argc) {
case 0:
return (Objany) (*cs_func)(cs_bound);
case 1:
return (Objany) (*cs_func)(cs_bound,ap[0]);
case 2:
return (Objany) (*cs_func)(cs_bound,ap[0],ap[1]);
case 3:
return (Objany) (*cs_func)(cs_bound,ap[0],ap[1],ap[2]);
default:
return (Objany) mipscall(cs_bound,cs_func,cs_argc,ap);
}
}
void
Callstate::Print(ostream& s)
{
s << form("(Callstate)this=0x%x, cs_func=0x%x, cs_argc=0x%x, cs_argvs=0x%x, cs_argvd=0x%x",
this, cs_func, cs_argc, cs_argvs, cs_argvd);
}
ostream& operator<<(ostream& s, Callstate& c)
{
c.Print(s);
return s;
}